#include "stm32f4xx_ll_tim.h"
#include "bsp_pwm_io.h"

typedef struct  
{
  TIM_TypeDef *TIMx;
  uint32_t Channel;
  float defaultDutyCycle;

}BSP_PWM_Config_Type;

#define MAX_PWM_CHANNEL (4)

static const BSP_PWM_Config_Type cstBSP_PWM_Config[MAX_PWM_CHANNEL]={
  {
    .TIMx = TIM4,
    .Channel=LL_TIM_CHANNEL_CH1,
    .defaultDutyCycle = 0,
  },
  {
    .TIMx = TIM4,
    .Channel=LL_TIM_CHANNEL_CH2,
    .defaultDutyCycle = 0,
  },
  {
    .TIMx = TIM4,
    .Channel=LL_TIM_CHANNEL_CH3,
    .defaultDutyCycle = 0,
  },
  {
    .TIMx = TIM4,
    .Channel=LL_TIM_CHANNEL_CH4,
    .defaultDutyCycle = 0,
  },
  
};

void bsp_pwm_io_init(void)
{
    /*Timer init code placed at MX_TIM4_Init*/

    for(int i=0;i<MAX_PWM_CHANNEL;i++){
      bsp_pwm_set_duty(i,cstBSP_PWM_Config[i].defaultDutyCycle);

      LL_TIM_CC_EnableChannel(cstBSP_PWM_Config[i].TIMx,cstBSP_PWM_Config[i].Channel);
    }
}

void bsp_pwm_set_duty(uint32_t u4ChannelID,float dutyCycle)
{
    TIM_TypeDef *TIMx;
    uint32_t fullCycle;
    uint32_t compareValue;

    TIMx = cstBSP_PWM_Config[u4ChannelID].TIMx;
    /*pwm period*/
    fullCycle = READ_REG(TIMx->ARR);
    compareValue = fullCycle*dutyCycle;

    switch (cstBSP_PWM_Config[u4ChannelID].Channel){
    case LL_TIM_CHANNEL_CH1:
      LL_TIM_OC_SetCompareCH1(TIMx,compareValue);
      break;
    case LL_TIM_CHANNEL_CH2:
      LL_TIM_OC_SetCompareCH2(TIMx,compareValue);
      break;
    case LL_TIM_CHANNEL_CH3:
      LL_TIM_OC_SetCompareCH3(TIMx,compareValue);
      break;
    case LL_TIM_CHANNEL_CH4:
      LL_TIM_OC_SetCompareCH4(TIMx,compareValue);
      break;
    default:break;
    }
}